<script setup lang="ts">
import type { Ref } from 'vue';

import type { GDVSceneConfig, GroupLayer } from '../historymap/index';

import { onMounted, provide, reactive, ref, watch } from 'vue';
import { onBeforeRouteLeave, useRouter } from 'vue-router';

import {
  BiGlobe,
  BxLayer,
  ElFullScreen,
  ElHomeFilled,
  PixelarticonsGrid,
  SimpleLineIconsQuestion,
  SvgMapIcon,
  SystemUiconsWrapBack,
} from '@vben/icons';

// @ts-ignore
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import * as turf from '@turf/turf';
import {
  ElDivider,
  ElIcon,
  ElLoading,
  ElMessage,
  ElPopover,
  ElSpace,
  ElTag,
  ElTooltip,
} from 'element-plus';
import mapboxGl from 'mapbox-gl';

import { historyApi, sceneApi } from '#/api';
import {
  BaseMapControl,
  Jump2EraControl,
  TimeRulerControl,
  YearSelection,
} from '#/components/scene-editor';
import { useSceneStore } from '#/store';
import {
  baseMapLayers,
  layerRenderUtil,
  normalizeConfig,
  switchBaseMap,
} from '#/utils';

import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';

const { initRender } = layerRenderUtil();
const base = import.meta.env.VITE_GLOB_MAPBOX_ASSETS_IP;
mapboxGl.accessToken =
  'pk.eyJ1IjoibmluamFhIiwiYSI6ImNsYXYzd3JwaDAyMGwzdm44ZmI3M212eHQifQ.h_dGMMOvQXNfmheNd0_j8A';
const sceneStore = useSceneStore();
const mapbox = reactive({
  map: null as any,
});
const router = useRouter();
const mapContainer: Ref<HTMLElement | undefined> = ref();
const currentSelectedLayer = ref(null as any);
const sceneLayersGroup = ref([] as any);
const sceneSourcesGroup = ref([] as any);
const loadingText = ref('场景加载中...');
const zoomText = ref();
const showCenter = ref('');
const mapMode = ref('mercator');
const mapModeList = ref([
  {
    id: 1,
    name: '平面',
    value: 'mercator',
  },
  {
    id: 2,
    name: '3D',
    value: 'globe',
  },
]);

const showTimeRuler = ref(true);
const showJump2Era = ref(true);
const isHistoryMode = ref(true);
provide('layerList', sceneLayersGroup);
provide('currentSelectedLayer', currentSelectedLayer);
let draw: MapboxDraw;
// 初始化空地图
const initMap = () => {
  return new Promise((resolve) => {
    mapbox.map = new mapboxGl.Map({
      container: 'map-container', // container ID
      style: {
        version: 8,
        sources: {},
        glyphs: `${base}/glyphs/fonts/{fontstack}/{range}.pbf`,
        sprite: `${base}/sprites/` + `mapstudio` + `/sprite`,
        layers: [],
      },
      center: [118.9, 32.08],
      zoom: 11,
      // projection: "globe",
      preserveDrawingBuffer: true,
      attributionControl: false,
    });

    resolve('地图初始化成功！正在加载场景配置项...');
    draw = new MapboxDraw({
      displayControlsDefault: true,
    });
    mapbox.map.addControl(
      new mapboxGl.NavigationControl({
        visualizePitch: true,
      }),
    );
    mapbox.map.addControl(draw);
    // 存储 featureId 对应的 Marker 实例
    const drawMarkers = new Map<string, mapboxgl.Marker>();
    let lastFeatureId: null | string = null;
    mapbox.map.on('draw.modechange', (e: any) => {
      const mode = e.mode;
      if (
        (mode === 'draw_polygon' || mode === 'draw_line_string') &&
        lastFeatureId
      ) {
        draw.delete(lastFeatureId);
        const oldMarker = drawMarkers.get(lastFeatureId);
        if (oldMarker) {
          oldMarker.remove();
          drawMarkers.delete(lastFeatureId);
        }
        lastFeatureId = null;
      }
    });
    mapbox.map.on('draw.create', (e: any) => {
      const feature = e.features[0];
      const featureId = feature.id;

      lastFeatureId = featureId;

      let markerText = '';
      let markerCoord: [number, number] = [0, 0];

      if (feature.geometry.type === 'Polygon') {
        const area = turf.area(feature);
        markerText = `${(area / 1_000_000).toFixed(2)} km²`;
        const centroid = turf.centroid(feature);
        markerCoord = centroid.geometry.coordinates as [number, number];
      }

      if (feature.geometry.type === 'LineString') {
        const line = turf.lineString(feature.geometry.coordinates);
        const length = turf.length(line, { units: 'kilometers' });
        markerText = `${length.toFixed(2)} km`;
        const midpointIndex = Math.floor(
          feature.geometry.coordinates.length / 2,
        );
        markerCoord = feature.geometry.coordinates[midpointIndex];
      }

      const markerEl = document.createElement('div');
      markerEl.className = 'draw-result-marker';
      markerEl.style.cssText = `
    padding: 6px 12px;
    background: rgba(255, 255, 255, 0.95);
    border-radius: 12px;
    font-size: 12px;
    font-weight: 500;
    color: #333;
    backdrop-filter: blur(8px);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(0, 0, 0, 0.08);
    transition: all 0.2s ease-in-out;
  `;

      markerEl.innerText = markerText;

      const marker = new mapboxGl.Marker(markerEl)
        .setLngLat(markerCoord)
        .addTo(mapbox.map);

      // 存储 marker
      drawMarkers.set(featureId, marker);
    });
    mapbox.map.on('draw.delete', (e: any) => {
      e.features.forEach((feature: any) => {
        const featureId = feature.id;
        const marker = drawMarkers.get(featureId);
        if (marker) {
          marker.remove();
          drawMarkers.delete(featureId);
        }
      });
    });

    // 添加比例尺
    const scale = new mapboxGl.ScaleControl({
      maxWidth: 120,
    });
    mapbox.map.addControl(scale);
    scale.setUnit('metric');
    // 添加定位控件
    mapbox.map.addControl(
      new mapboxGl.GeolocateControl({
        positionOptions: {
          enableHighAccuracy: true,
        },
        trackUserLocation: true,
      }),
    );

    mapbox.map.on('zoom', () => {
      zoomText.value = mapbox.map.getZoom().toFixed(2);
    });
    mapbox.map.on('mousemove', (e: any) => {
      showCenter.value = `(${String(e.lngLat.lng.toFixed(5))}，${String(
        e.lngLat.lat.toFixed(5),
      )})`;
    });
  });
};

const handleSwitchMap = ({ id, type, label }: any) => {
  const lastLayerId = mapbox.map.getStyle().layers[0]
    ? mapbox.map.getStyle().layers[0].id
    : '';

  const groupId = `group_${id}`;
  let lastGroupId = '';
  if (sceneStore.currentSceneConfig.layers.length > 0) {
    lastGroupId =
      sceneStore.currentSceneConfig.layers[
        sceneStore.currentSceneConfig.layers.length - 1
      ]?.id || '';
  }
  // 同类型不切换
  if (lastGroupId === groupId) return;

  // 存在底图的情况下，删除图层列表对应项
  const isBaseMapExist = sceneStore.currentSceneConfig.layers.some(
    (layer: any) =>
      ['group_img_map', 'group_ter_map', 'group_vec_map'].includes(layer.id),
  );
  if (isBaseMapExist) {
    sceneStore.currentSceneConfig.layers.pop();
  }

  switchBaseMap(mapbox.map, type, lastLayerId);

  // 更新图层列表
  if (type === 'blank') return;
  const baseMapGroup = {
    id: groupId,
    name: `${label}底图`,
    layers: [] as any,
    organizationType: 'groupLayer',
  };
  switch (type) {
    case 'image': {
      baseMapGroup.layers = [baseMapLayers.image[1], baseMapLayers.image[0]];

      break;
    }
    case 'terrain': {
      baseMapGroup.layers = [
        baseMapLayers.terrain[1],
        baseMapLayers.terrain[0],
      ];

      break;
    }
    case 'vector': {
      baseMapGroup.layers = [baseMapLayers.vector[1], baseMapLayers.vector[0]];

      break;
    }
  }
  sceneStore.currentSceneConfig.layers.push(baseMapGroup as GroupLayer);
};

const toggleMapMode = (mode: any, init: boolean = false) => {
  const { value, name } = mode;
  if (value === mapMode.value) return;
  mapMode.value = value;
  mapbox.map.setProjection(value);
  if (value === 'globe') {
    mapbox.map.setFog({});
  } else {
    mapbox.map.setFog(null);
  }
  if (!init) {
    sceneStore.currentSceneConfig.mapParams.mapMode =
      value === 'mercator' ? 0 : 1;
    ElMessage.success(`已切换至${name}模式`);
  }
};

const getDefaultConfig = (): GDVSceneConfig => {
  return {
    sceneId: '',
    sources: [],
    layers: [],
    pos: {
      bearing: 0,
      pitch: 0,
    },
    mapParams: {
      center: [118.9, 32.08],
      zoom: 11,
      mapMode: 0, // 0:'mercator',1:'globe'
      historyMap: null,
    },
    sprite: 'mapstudio',
  };
};

const getSceneConfig = async () => {
  const config = await sceneApi.getGDVSceneConfig(
    sceneStore.editingScene.sceneId,
  );
  delete config.id;
  sceneStore.setCurrentSceneConfig(normalizeConfig(config));
  sceneLayersGroup.value = sceneStore.currentSceneConfig.layers;
  sceneSourcesGroup.value = sceneStore.currentSceneConfig.sources;
  return '地图场景配置项加载完毕！正在渲染数据...';
};

const requestMapConfig = () => {
  // 如果是新建空场景，手动初始化一个空配置
  return sceneStore.editingScene.sceneId === ''
    ? new Promise<string>((resolve) => {
        sceneStore.setCurrentSceneConfig(getDefaultConfig());
        resolve('地图场景配置项加载完毕！');
      })
    : getSceneConfig();
};

const initMapMode = () => {
  const mode = sceneStore.currentSceneConfig.mapParams.mapMode
    ? {
        id: 2,
        name: '3D',
        value: 'globe',
      }
    : {
        id: 1,
        name: '平面',
        value: 'mercator',
      };
  toggleMapMode(mode, true);
};

const initMapState = (duration = 1500) => {
  mapbox.map.easeTo({
    center: sceneStore.currentSceneConfig.mapParams.center, // 目标中心点坐标
    zoom: sceneStore.currentSceneConfig.mapParams.zoom, // 目标缩放级别
    bearing: sceneStore.currentSceneConfig.pos.bearing, // 目标旋转角度（以度为单位，可选）
    pitch: sceneStore.currentSceneConfig.pos.pitch, // 目标俯仰角（以度为单位，可选）
    duration, // 动画持续时间（以毫秒为单位，可选）
  });
};

const backScene = () => {
  router.back();
};

const handletoggleFullScreen = () => {
  const mapContainer = mapbox.map.getContainer();

  //  兼容不同浏览器
  const rfs =
    mapContainer.requestFullscreen ||
    mapContainer.webkitRequestFullScreen ||
    mapContainer.mozRequestFullScreen ||
    mapContainer.msRequestFullscreen;

  if (rfs) {
    rfs.call(mapContainer);
  }
};

const changeSpriteLib = (sprite: string) => {
  // console.log(sprite);
  const style = mapbox.map.getStyle();
  style.sprite = `${base}/sprites/${sprite}/sprite`;

  mapbox.map.setStyle(style);
};

const availableYears: number[] = [
  // BC3200 到 BC2000，每隔 50 年
  ...Array.from({ length: (3200 - 2000) / 50 + 1 }, (_, i) => -3200 + i * 50),
  // BC2000 到 BC1000，每隔 10 年
  ...Array.from({ length: (2000 - 1000) / 10 + 1 }, (_, i) => -2000 + i * 10),
  // BC1000 到 AD1900，每隔 1 年
  ...Array.from({ length: 1900 + 1000 + 1 }, (_, i) => i - 1000),
];

const formatYearLabel = (year: number): string => {
  return year < 0 ? `BC${-year}` : `AD${year}`;
};

const parseYearString = (yearStr: string): number => {
  if (yearStr.startsWith('BC')) return -Number(yearStr.slice(2));
  if (yearStr.startsWith('AD')) return Number(yearStr.slice(2));
  return Number(yearStr); // fallback
};

const findNearestAvailableYear = (targetYear: number): number => {
  if (targetYear === 0) return 1;
  if (availableYears.includes(targetYear)) return targetYear;

  let nearest = availableYears[0] || 750;
  let minDiff = Math.abs(nearest - targetYear);

  for (const year of availableYears) {
    const diff = Math.abs(year - targetYear);
    if (diff < minDiff) {
      nearest = year;
      minDiff = diff;
    }
  }
  return nearest;
};

const getHistoryStyleWithLayers = (style: any) => {
  // 先去除之前的历史图层
  const sourcesNoHistory = mapbox.map.getStyle().sources;
  delete sourcesNoHistory.dlsgis_his_regime;
  const layersNoHistory = mapbox.map
    .getStyle()
    .layers.filter((layer: any) => layer.source !== 'dlsgis_his_regime');
  // 提取出底图和自定义图层
  const baseMapIds = new Set(
    Object.values(baseMapLayers).flatMap((layer) =>
      layer.map((item) => item.id),
    ),
  );
  const baseMaps = layersNoHistory.filter((layer: any) =>
    baseMapIds.has(layer.id),
  );
  const customLayers = layersNoHistory.filter(
    (layer: any) => !baseMapIds.has(layer.id),
  );

  // 底图放到最底下
  if (baseMaps.length > 0) {
    style.layers = [...baseMaps, ...style.layers];
  }

  style.sources = { ...style.sources, ...sourcesNoHistory };
  // 自定义图层按照顺序放到最上面
  style.layers = [...style.layers, ...customLayers];
  return style;
};

const fetchHistoryLayerStyle = async (year: string) => {
  const parsedYear = parseYearString(year); // 转为数字
  const nearestYear = findNearestAvailableYear(parsedYear); // 找最近的
  const nearestYearStr = formatYearLabel(nearestYear); // 转回 BC/AD 形式

  // 如果找到了不同的年份，提示用户
  if (nearestYear !== parsedYear) {
    ElMessage.warning(
      `暂无 ${year} 年的数据，已切换至最近的 ${nearestYearStr} 年的疆域数据`,
    );
  }
  // 用最近可用的 BC/AD 年份发请求
  const response = await fetch(historyApi.getHistoryMapStyle(nearestYearStr));
  if (!response.ok) throw new Error('样式加载失败');

  let style = await response.json();
  style.sources.dlsgis_his_regime.tiles = [
    historyApi.getHistoryTilesURL(nearestYearStr),
  ];
  style.glyphs = `${base}/glyphs/fonts/{fontstack}/{range}.pbf`;
  style.sprite = `${base}/sprites/${sceneStore.currentSceneConfig.sprite}/sprite`;
  style = getHistoryStyleWithLayers(style);
  return style;
};

const selectedRange = ref<[number, number]>([700, 750]);
const dropdownYear = ref(750);

const handleUpdateTimeRange = async (timeRange: [number, number]) => {
  selectedRange.value = timeRange;
  isHistoryMode.value = true;

  const endLayer = timeRange[1] || 0;
  const formattedYear = endLayer < 0 ? `BC${-endLayer}` : `AD${endLayer}`;
  dropdownYear.value = endLayer;
  const style = await fetchHistoryLayerStyle(formattedYear);

  mapbox.map.setStyle(style);
  if (mapMode.value === 'globe') {
    mapbox.map.on('style.load', () => {
      mapbox.map.setFog({});
    });
  }
  showTimeRuler.value = true;

  if (isHistoryMode.value) {
    sceneStore.currentSceneConfig.mapParams.historyMap = timeRange[1];
  }
  mapbox.map.setZoom(3);
};

const initHistoryMap = () => {
  const year = sceneStore.currentSceneConfig.mapParams.historyMap;
  if (year) {
    handleUpdateTimeRange([year - 50, year]);
  }
};

const onYearDropdownChange = (year: number) => {
  handleUpdateTimeRange([year - 50, year]);
};

onMounted(async () => {
  const sceneLoading = ElLoading.service({
    lock: true,
    text: loadingText.value,
    background: 'rgba(0, 0, 0, 0.7)',
  });
  sceneLoading.setText('初始化地图中，请稍后...');
  sceneLoading.setText((await initMap()) as string);
  sceneLoading.setText((await requestMapConfig()) as string);
  initRender(mapbox.map);

  sceneLoading.setText('初始化地图模式...');
  initMapMode();
  sceneLoading.setText('加载历史地图数据...');
  initHistoryMap();

  sceneLoading.close();
  watch(
    () => sceneStore.currentSceneConfig.sprite,
    (newVal: string) => {
      changeSpriteLib(newVal);
    },
  );
  watch(
    () => sceneStore.currentSceneConfig.layers,
    () => {
      sceneLayersGroup.value = sceneStore.currentSceneConfig.layers;
    },
    {
      deep: true,
    },
  );
});

onBeforeRouteLeave((_to, _from, next) => {
  next();
});
</script>

<template>
  <div class="allcontainer">
    <div class="header">
      <div class="left-btn">
        <ElIcon size="22" color="#ccc" @click="backScene">
          <SystemUiconsWrapBack />
        </ElIcon>
      </div>
      <div class="title">
        <ElIcon size="22">
          <SvgMapIcon />
        </ElIcon>
        <span>历史疆域地图</span>
      </div>
      <div class="right-btn">
        <ElSpace :size="22">
          <ElTooltip placement="bottom" content="全屏">
            <ElIcon size="21" color="#ccc" @click="handletoggleFullScreen">
              <ElFullScreen />
            </ElIcon>
          </ElTooltip>
          <ElTooltip placement="bottom" content="帮助">
            <ElIcon size="21" color="#ccc">
              <SimpleLineIconsQuestion />
            </ElIcon>
          </ElTooltip>
        </ElSpace>
      </div>
    </div>
    <div class="body">
      <div class="map-box">
        <div id="map-container" ref="mapContainer">
          <ElTag class="mapZoomLngLat" type="info">
            Zoom:{{ zoomText }} &nbsp; LngLat:{{ showCenter }}
          </ElTag>
          <div class="homemap-control">
            <ElIcon
              class="control-btn"
              size="27"
              title="回到初始状态"
              @click="initMapState(0)"
            >
              <ElHomeFilled />
            </ElIcon>
          </div>
          <div class="mapmode-control">
            <ElPopover
              placement="left-end"
              :width="80"
              trigger="click"
              :teleported="false"
              transition="none"
              :hide-after="0"
              :popper-style="{ minWidth: '80px', padding: '5px' }"
            >
              <template #default>
                <div class="mapmode-sub-control">
                  <ElIcon
                    size="27"
                    class="sub-control-btn"
                    title="平面"
                    :class="{
                      'mode-active': mapMode === mapModeList[0]?.value,
                    }"
                    @click="toggleMapMode(mapModeList[0])"
                  >
                    <PixelarticonsGrid />
                  </ElIcon>
                  <ElDivider
                    direction="vertical"
                    border-style="hidden"
                    style="margin-right: 3px; margin-left: 3px"
                  />
                  <ElIcon
                    size="24"
                    class="sub-control-btn"
                    title="3D"
                    :class="{
                      'mode-active': mapMode === mapModeList[1]?.value,
                    }"
                    @click="toggleMapMode(mapModeList[1])"
                  >
                    <BiGlobe />
                  </ElIcon>
                </div>
              </template>
              <template #reference>
                <ElIcon
                  v-if="mapMode === 'mercator'"
                  size="27"
                  class="control-btn"
                  title="平面"
                >
                  <PixelarticonsGrid />
                </ElIcon>
                <ElIcon v-else size="25" class="control-btn" title="3D">
                  <BiGlobe />
                </ElIcon>
              </template>
            </ElPopover>
          </div>
          <div class="basemap-control">
            <ElPopover
              placement="left"
              :width="220"
              trigger="click"
              :teleported="false"
              transition="none"
              :hide-after="0"
              :popper-style="{ padding: '2px' }"
            >
              <template #default>
                <BaseMapControl @switch-map="handleSwitchMap" />
              </template>
              <template #reference>
                <ElIcon size="28" class="control-btn" title="底图">
                  <BxLayer />
                </ElIcon>
              </template>
            </ElPopover>
          </div>
        </div>
        <div class="time-ruler h-20" v-if="showTimeRuler">
          <TimeRulerControl
            :selected-range="selectedRange"
            @update:selected-range="handleUpdateTimeRange"
          />
        </div>
        <div v-if="showJump2Era">
          <Jump2EraControl
            v-model="showJump2Era"
            @update:selected-range="handleUpdateTimeRange"
            :is-jump-2-era-show="showJump2Era"
            @close-jump2era-show-dialog="showJump2Era = false"
          />
        </div>
        <div v-if="showTimeRuler">
          <YearSelection
            v-model="dropdownYear"
            @change="onYearDropdownChange"
            :selected-range="selectedRange"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
@keyframes fade-in-right {
  from {
    right: 8vw;
    opacity: 0;
  }

  to {
    right: 9vw;
    opacity: 1;
  }
}

.menuCon {
  display: flex;
  flex-direction: column;
  height: 100%;
  border-right: 1px solid rgb(168 166 166);
}

.editContainer,
.settingPannel {
  box-sizing: border-box;
  flex-shrink: 0;
  width: 100%;
  width: 340px;
  height: 100%;
  // overflow: hidden;
  border-right: 1px solid rgb(202 202 202);
}

/* .resourceManagement {
  width: 100%;
  height: 100%;
} */

/* .dataSourcePannel {
  width: 100%;
  height: 0%;
} */

.dataSourcePannel2 {
  width: 100%;
  height: 100%;

  /* flex: 1; */
}

.layerPannel {
  width: 100%;
  height: 100%;

  /* flex: 1; */
}

.map-box {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  // padding: 5px 0 0 0;
  // background-color: #e4e4e4;
  background-color: #f2f3f7;
  border-top: 1px solid #fff;
}

#map-container {
  position: relative;
  z-index: 10;
  flex: 1;
  width: 100%;
  // height: 100%;
}

.allcontainer {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  overflow: hidden;

  /* 禁用滚动 */
}

.header {
  z-index: 11;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 50px;
  // background-color: #fff;
  background-color: #2e3138;
  border-bottom: rgb(175 175 175 / 50%) 1px solid;
  box-shadow: -10px 10px 4px -12px rgb(0 0 0 / 50%);

  /* inset 表示内阴影 */

  .common-btn {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 80%;
  }

  .left-btn {
    /* stylelint-disable-next-line at-rule-no-unknown */
    @extend .common-btn;

    width: 56px;
    border-right: #ccc 1px solid;
  }

  .right-btn {
    /* stylelint-disable-next-line at-rule-no-unknown */
    @extend .common-btn;

    padding-right: 22px;
    // width: 120px;
  }

  .common-btn .el-icon:hover {
    color: #fff;
    cursor: pointer;
  }

  .title {
    display: flex;
    align-items: center;
    font-size: 1.2rem;
    font-weight: 600;
    // color: #333;
    color: #ccc;
    letter-spacing: 1px;

    span {
      // width: 100px;
      height: 30px;
      margin-left: 5px;
      line-height: 30px;
    }
  }
}

.body {
  display: flex;
  flex: 1;
  width: 100%;
}

.menuItemsCon {
  height: 100%;
}

.menu-btn {
  /* 导航栏实际高度比header高，遮住了 */
  z-index: 10;
  display: flex;

  /* text-align: center; */
  align-items: center;
  justify-content: center;
  height: 57px;
  color: #bababa;
  cursor: pointer;
  user-select: none;
  background-color: #2b2b2b;

  &:hover {
    color: #fff;
    background-color: #151515;
  }
}

.icon {
  width: 1em;
  height: 1em;
  overflow: hidden;
  vertical-align: -0.15em;
  fill: currentcolor;
}

.el-menu {
  --el-menu-base-level-padding: 16px;

  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
  user-select: none;
  border: none;

  // .el-menu-item {
  //   padding: 0 calc(var(--el-menu-base-level-padding) + 8px) 0
  //     var(--el-menu-base-level-padding);
  // }
}

.el-menu-item.is-active {
  width: 100%;
  font-weight: bold;
  background-color: #151515 !important;
}

.el-menu-item:hover {
  /* width: 100%; */
  color: #fff;
  background-color: #151515;
}

.el-menu-item.is-active::before {
  position: absolute;
  top: 0;
  left: 0;
  display: inline-block;
  width: 3px;
  height: 100%;
  content: '';
  background-color: #2f89fc;
}

/* 隐藏logo */
:deep(.mapboxgl-ctrl-logo) {
  display: none !important;
}

:deep(.mapboxgl-ctrl-bottom-right) {
  display: none !important;
}

.mapZoomLngLat {
  position: absolute;
  right: 60px;
  bottom: 10px;
  z-index: 10;
  font-size: 13px;
  background-color: #fff !important;
}

.mapStyleBtn {
  position: absolute;
  top: 40px;
  right: 60px;
  z-index: 10;
  font-size: 13px;
  background-color: #fff !important;
}

.mapmode-control {
  position: absolute;
  right: 20px;
  bottom: 70px;
  z-index: 10;

  .mapmode-sub-control {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 70px;
    height: 30px;

    .sub-control-btn {
      width: 30px;
      height: 100%;
      padding: 2px;
      border: #e7e7e7 solid 2px;
      border-radius: 5px;

      &:not(.mode-active):hover {
        color: #2f89fc;
        cursor: pointer;
        border: #2f89fc solid 2px;
      }
    }

    .mode-active {
      color: #2f89fc;
      border: #2f89fc solid 2px;
    }
  }
}

.basemap-control {
  position: absolute;
  right: 20px;
  bottom: 20px;
  z-index: 10;
}

.homemap-control {
  position: absolute;
  right: 20px;
  bottom: 120px;
  z-index: 10;
}

.export-control {
  position: absolute;
  right: 20px;
  bottom: 170px;
  z-index: 10;
}

.export-control,
.mapmode-control,
.basemap-control,
.homemap-control {
  .control-btn {
    width: 40px;
    height: 40px;
    color: #4d4d4d;
    background-color: rgb(255 255 255 / 50%);
    border: 1px solid rgb(175 175 175 / 50%);
    border-radius: 50%;
    box-shadow:
      0 4px 6px rgb(0 0 0 / 10%),
      0 1px 3px rgb(0 0 0 / 8%);

    /* 初始阴影效果 */
    transition: all 0.3s ease;

    &:hover {
      color: #2f89fc;
      cursor: pointer;
      background-color: rgb(255 255 255 / 80%);
      box-shadow:
        0 15px 30px rgb(0 0 0 / 20%),
        0 10px 15px rgb(0 0 0 / 10%);

      /* 悬浮时的更大阴影 */
      transform: translateY(-6px);

      /* 上浮效果 */
    }
  }
}

.animation-control {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 10;
}

/* 保存对话框 */
.my-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  padding-top: 10px;
  padding-bottom: 5px;
  padding-left: 20px;
  font-size: 18px;
}

:deep(.save-scene-dialog .el-dialog) {
  height: auto;
  border-radius: 20px;
  box-shadow: 0 0 50px rgb(0 0 0 / 50%);
}

.row-style {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 20px;
}

.mybtn {
  width: 80px;
  height: 30px;
  font-weight: bolder;
  letter-spacing: 1px;
  border-radius: 3px;
}

/* 大模型css */
.btn {
  position: absolute;
  right: 2vw;
  bottom: 4vh;
  z-index: 999;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  width: 120px;
  height: 45px;
  font-family: Dosis, sans-serif;
  font-size: 24px;
  color: white;
  cursor: pointer;
  background-image: linear-gradient(135deg, #fff 0%, #fff 100%);
  border: none;
  border-radius: 30px;
  outline: none;
  box-shadow: 0 20px 30px -6px rgb(255 255 255 / 50%);
  transition: all 0.3s ease-in-out;
}

.btn:active {
  opacity: 0.5;
}

/* robot */
.aiAssitant {
  bottom: 2vh;
  z-index: 999;
  display: flex;
  justify-content: center;
}

.aiImage {
  display: flex;
  align-items: center;
  justify-content: center;
}

.aiImage:hover {
  scale: 1.1;
}

.dianwo {
  font-size: small;
  color: #000;
}

.dianwo:hover {
  color: #5ca7f3;
  cursor: pointer;
}

.aiChatPannel {
  position: absolute;
  right: 9vw;
  bottom: 4vh;
  z-index: 1999;
  width: 25vw;
  height: 66vh;
  padding: 5px;
  background-color: rgb(226 232 240);
  border-radius: 15px;
  box-shadow: -10px 12px 8px -12px #000;
  animation: fade-in-right 0.5s forwards;
}

.draw-result-marker {
  padding: 4px 8px;
  font-size: 12px;
  white-space: nowrap;
  background: white;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 30%);
}
</style>
